{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Use OSMnx to plot street network over place shape\n",
    "\n",
    "Author: [Geoff Boeing](https://geoffboeing.com/)\n",
    "\n",
    "This example uses Portland, Maine - a city with several islands within its municipal boundaries. Thus, we set `retain_all=True` when getting the network so that we keep all the graph components, not just the largest connected component.\n",
    "\n",
    "  - [Documentation](https://osmnx.readthedocs.io/)\n",
    "  - [Journal article and citation info](https://geoffboeing.com/publications/osmnx-paper/)\n",
    "  - [Code repository](https://github.com/gboeing/osmnx)\n",
    "  - [Examples gallery](https://github.com/gboeing/osmnx-examples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import osmnx as ox\n",
    "\n",
    "ox.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the place boundaries\n",
    "place = \"Portland, Maine\"\n",
    "gdf = ox.geocode_to_gdf(place)\n",
    "\n",
    "# get the street network, with retain_all=True to retain all the disconnected islands' networks\n",
    "G = ox.graph_from_place(place, network_type=\"drive\", retain_all=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot the network, but do not show it or close it yet\n",
    "fig, ax = ox.plot_graph(\n",
    "    G,\n",
    "    show=False,\n",
    "    close=False,\n",
    "    bgcolor=\"#333333\",\n",
    "    edge_color=\"w\",\n",
    "    edge_linewidth=0.3,\n",
    "    node_size=0,\n",
    ")\n",
    "\n",
    "# to this matplotlib axis, add the place shape(s)\n",
    "gdf.plot(ax=ax, fc=\"k\", ec=\"#666666\", lw=1, alpha=1, zorder=-1)\n",
    "\n",
    "# optionally set up the axes extents\n",
    "margin = 0.02\n",
    "west, south, east, north = gdf.unary_union.bounds\n",
    "margin_ns = (north - south) * margin\n",
    "margin_ew = (east - west) * margin\n",
    "ax.set_ylim((south - margin_ns, north + margin_ns))\n",
    "ax.set_xlim((west - margin_ew, east + margin_ew))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice this municipal boundary is an administrative boundary, not a physical boundary, so it represents jurisdictional bounds, not individual physical features like islands. To retrieve individual islands' geometries, use the `features` module to search for features matching certain OSM tags:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "islands = ox.features_from_place(place, tags={\"place\": [\"island\", \"islet\"]})\n",
    "islands.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python (ox)",
   "language": "python",
   "name": "ox"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
